/* 拓扑排序
* 1.做法:
    (1) 合并两个集合
    (2) 查询某个元素的祖宗节点
    (3) 记录方法:
        记录每个集合大小: 绑定到根节点上
        记录每个点到根节点的距离: 绑定到每个元素上

* 本题: 
    有依赖背包
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
#include <algorithm> 
// #define ONLINE_GUDGE
using namespace std;
using PII = pair<int, int>;
#define wei first
#define val second
const int N = 1e4+10;

int n, m, w, f[N], fa[N];
PII wv[N];

inline int find(int x)
{
    if(x == fa[x]) return x;
    else return fa[x] = find(fa[x]);
}

inline void merge(int x, int y) // x <= y
{
    x = find(x), y = find(y);
    if(x == y) return;
    fa[y] = x;
    wv[x].wei += wv[y].wei; 
    wv[x].val += wv[y].val;
}

inline void Print()
{
    cout << "fa[]:\n";
    for(int i = 1; i <= n; i++){
        printf("fa[%d]:%d wv:(weight:%d, val:%d)\n", i, fa[i], wv[i].wei, wv[i].val);
    }
}

int main()
{

    #ifdef ONLINE_JUDGE
    ios::sync_with_stdio(false);   
	cin.tie(0);
    #else
    freopen("./in.txt","r",stdin);
    #endif
    
    cin >> n >> m >> w; 

    for(int i = 1; i <= n; i++){
        fa[i] = i;
        cin >> wv[i].wei >> wv[i].val;
    } 
    //Print();
    for(int i = 1; i <= m; i++){
        int x, y; cin >> x >> y;
        if(x > y) swap(x, y);
        merge(x, y);
    }


    int res = 0;

    for (int i = 1; i <= n; i ++ ) // 0-1背包
        if(fa[i] == i) 
            for (int j = w; j >= wv[find(i)].wei; j -- )
                f[j] = max(f[j], f[j - wv[find(i)].wei] + wv[find(i)].val);
    cout << f[w] << endl;
    //Print();
    return 0;
}
